/*
function main(){
    Java.perform(function (){
        // 定位类指针
        // var Utils = Java.use("需要填写类名")
        var Utils = Java.use("com.luoge.com.Utils")
        Utils.处理德方法名.implementation = function (){
             编写德业务逻辑
        }
    })
}
setImmediate(main)
*/

// 编写静态方法hook
function demo() {
    var Utils = Java.use("com.luoge.com.Utils")
    Utils.getCalc.implementation = function (arg1, arg2) {
        console.log("参数1--》" + arg1)
        console.log("参数2--》" + arg2)
        var res = this.getCalc(arg1, arg2)
        console.log("result-->" + res)
        return 10000;
    }
}

function demo1() {
    var Utils = Java.use("com.luoge.com.Utils")
    Utils.setFlag.implementation = function (arg) {
        console.log("arg1-->" + arg)
        return this.setFlag("how are you")
    }
    Utils.getFlag.implementation = function () {
        var res = this.getFlag();
        console.log(res)
        return res
    }

}

// hook重载方法
function demo2() {
    var Utils = Java.use("com.luoge.com.Utils")
    Utils.getOver.overload('int').implementation = function (arg) {
        console.log(arg)
        var res = this.getOver(arg)
        console.log(res)
        return res
    }
    // 参数类型是方法
    Utils.getOver.overload('com.luoge.com.Money').implementation = function (a) {
        console.log('重载方法')
        var res = this.getOver(a)
        console.log(res)
        return res
    }
}

// hook全部重载方法
function demo3() {
    var targetClass = Java.use('com.luoge.com.Utils');
    // 使用 overloads 函数获取所有重载方法
    var methods = targetClass['getOver'].overloads;
    console.log(methods)
    console.log(methods.length, '多少个重载方法')

    methods.forEach(function (method) {
        console.log("1" + method)
        method.implementation = function () {
            console.log("方法被调用--》" + method)
            // 调用原始方法
            // 添加你德自定义逻辑
            return method.apply(this, arguments)
        }
    })
}

// 对重载方法改写
function demo4() {
    var Utils = Java.use('com.luoge.com.Utils');
    var overloadsArr = Utils.getOver.overloads;
    for (var i = 0; i < overloadsArr.length; i++) {
        overloadsArr[i].implementation = function () {
            var par = "";
            for (var j = 0; j < overloadsArr.length; j++) {
                par += arguments[j] + " ";
            }
            ;
            console.log("Utils.getOver par--->" + par)
            var result = this.getOver.apply(this, arguments)

            var result1 = Utils.getOver(); // Call getOver()
            console.log("Result 无参重载 " + result1);
            // var result2 = Utils.getOver.overload('int').call(this, 888); // Call getOver(int num)
            // console.log("Result 有参重载" + result2);
            //
            // // 调用带有参数的类方法
            var result22 = Utils.getOver(10);
            console.log("Result 有参重载: " + result22);


            //  // 使用overload调用特定的重载
            var MoneyClass = Java.use('com.luoge.com.Money');
            var moneyInstance = MoneyClass.$new();  // 创建 Money 类的实例
            var result3 = Utils.getOver.overload('com.luoge.com.Money').call(this, moneyInstance);
            console.log("Result 特定参数重载: " + result3);

            return result


        }
    }
}

// 构造方法
function demo5() {
    let Money = Java.use("com.luoge.com.Money");
    Money["$init"].overload('java.lang.String', 'int').implementation = function (str, i) {
        console.log(`Money.$init is called: str=${str}, i=${i}`);
        str = "夏洛";
        i = 8888;
        this["$init"](str, i);
    };


}

// 主动调用
function demo6() {
    // 新建对象调用
    var res = Java.use("com.luoge.com.Money").$new("菲菲", 18).getInfo()
    // console.log(res);

    // 获取已有的对象调用  一般再rpc会经常使用
    Java.choose("com.luoge.com.Money", {
        onMatch: function (obj) {
            console.log("主动调用--》" + obj.getInfo());
        },
        onComplete: function () {
            console.log("内存中搜索完毕")
        }
    })

}

// 类操作
function demo7() {
    var money = Java.use("com.luoge.com.Money");
    console.log(JSON.stringify(money.flag.value));
    // 对字段进行修改
    money.flag.value = "菲菲"
    console.log(money.flag.value, "修改之后的结果")

    Java.choose("com.luoge.com.Money", {
        onMatch: function (obj) {
            obj._name.value = "娜娜"; // 同字段名字 前面加一个 下划线
            console.log(obj._name.value, "修改")
            console.log(obj.num.value)

        },
        onComplete: function () {
        }
    })


}

// 内部类hook
function demo8() {
    var InnerClass = Java.use("com.luoge.com.Money$innerClass")
    console.log(InnerClass)
    InnerClass.$init.overload("java.lang.String", "int").implementation = function (name, num) {
        console.log(name, num)

        // 主动调用原始函数
        this.$init(name, num)

        console.log(this.outPrint());

        return this.$init(name, num)
    }
}

// 类操作 字段 构造方法  方法  内部类
function demo9() {
    // console.log(Java.enumerateLoadedClassesSync().join('\n'))

    // 针对某一个类进行操作
    var money = Java.use("com.luoge.com.Money");
// var methods = money.class.getDeclaredMethods()
// for (var i=0;i<methods.length; i++){
//     console.log(methods[i].getName());
// }

// 获取构造函数
    var contructors = money.class.getDeclaredConstructors();
    console.log(contructors)
    for (var jj = 0; jj < contructors.length; jj++) {
        var contruct = contructors[jj]
        // console.log("contructors--->" + contruct.toString())
        // console.log("contructors getName --->" + contruct.getName())
    }

    // hook字段
    var field = money.class.getDeclaredFields()
    for (var s = 0; s < field.length; s++) {
        var fd = field[s]
        // console.log("field-->" + fd.toString())
    }

    // hook全部内部类
    var classes = money.class.getDeclaredClasses();
    console.log(classes)
    for (var h = 0; h < classes.length; h++) {
        var cla = classes[h]
        console.log("classes-->" + cla.toString())
        console.log("classesxxxx-->" + cla.getName())
    }

}

// hashmap参数
function demo10() {
    var BufferMap = Java.use(`com.luoge.com.BufferMap`)
    BufferMap.show.implementation = function (arg) {

        // 可以再frida里面写循环
        var key = arg.keySet()
        var it = key.iterator();
        var res = "";
        while (it.hasNext()) {
            var keys = it.next();
            // console.log(keys)
            var values = arg.get(keys)
            // console.log(values)
            res += values
        }
        console.log(res)

        // 添加数据返回 java hashmap他与python字典会有差异 {name=xxx}, name=aaa,age=18  主动调用可以这么来做

        arg.put("name", "xialuo");
        arg.put("names", "菲菲");

        var result = this.show(arg)
        return result

    }
}


function showStacks() {
    Java.perform(function () {
        console.log(Java.use("android.util.Log").getStackTraceString(
            Java.use("java.lang.Throwable").$new()
        ));
    })
}

function hook_sort() {

    var Collections = Java.use('java.util.Collections');
    // Hook sort() 方法
    Collections.sort.overload("java.util.List").implementation = function (list) {
        console.log('Hooked Collections.sort()');
        console.log('List: ' + list.toString());
        // 可在此处对参数进行修改或记录
        // 使用 Java.cast 进行类型转换 将list转换成ArrayList类型
        var res = Java.cast(list, Java.use("java.util.ArrayList"))
        console.log('List list-->', res)
        // 调用原始的 sort() 方法
        // 从这里看堆栈 找源码出现的位置
        return this.sort(list);
    };


    Collections.sort.overload("java.util.List", "java.util.Comparator").implementation = function (a, b) {
        console.log('Hooked Collections.sort()');
        var res = Java.cast(a, Java.use("java.util.ArrayList"))
        console.log('Comparator list-->', res)
        return this.sort(a, b);
    };
}

function hook_json() {
    console.log("===============hook josn ================")
    var JSONObject = Java.use('org.json.JSONObject');
// Hook JSONObject.put() 方法
    JSONObject.put.overload('java.lang.String', 'java.lang.Object').implementation = function (key, value) {
        // console.log('Hooked JSONObject.put()');
        // console.log('Key: ' + key.toString());
        // console.log('Value: ' + value.toString());
        // 可在此处对参数进行修改或记录
        // 调用原始的put()方法
        if (key == "Encrypt") {
            // showStacks()
        }
        return this.put(key, value);
    };

// Hook JSONObject.getString() 方法  从json里面取值
    JSONObject.getString.overload('java.lang.String').implementation = function (key) {
        console.log('Hooked JSONObject.getString()');
        console.log('Key: ' + key.toString());
        // 调用原始的getString()方法
        //     showStacks()
        var result = this.getString(key);
        // 可在此处对返回值进行修改或记录
        return result;
    };
}

function get_String() {
    var StringClass = Java.use('java.lang.String');
    // Hook String 类的构造函数
    StringClass.getBytes.overload().implementation = function () {
        console.log('Original Value');
        // 可在此处修改传入的字符串参数
        var res = this.getBytes();
        var newString = StringClass.$new(res)
        // 输出修改后的值
        console.log('Modified Value: ' + newString);
        return res;
    };

    // Hook String 类的静态方法
    StringClass.getBytes.overload('java.lang.String').implementation = function (obj) {
        console.log('Hooked String.valueOf()');
        // 可在此处修改传入的对象参数
        var res = this.getBytes(obj);
        var newString = StringClass.$new(res, obj)
        // 输出修改后的结果
        console.log('getBytes: ' + newString)
        return res
    }


}

function hook_StringBuilder() {

    var stringBuilderClass = Java.use("java.lang.StringBuilder");
    stringBuilderClass.toString.implementation = function () {
        var res = this.toString.apply(this, arguments)
        // if (res.includes("_sig")){
        //     showStacks()
        // }

        return res
    }

    let ApiSignatureHelper = Java.use("com.douban.frodo.network.ApiSignatureHelper");
    ApiSignatureHelper["a"].overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation = function (str, str2, str3) {
        console.log(`ApiSignatureHelper.m28657a is called: str=${str}, str2=${str2}, str3=${str3}`);
        let result = this["a"](str, str2, str3);
        console.log(`ApiSignatureHelper.m28657a result=${result}`);
        return result;
    };

}


function main() {
    Java.perform(function () {

        get_String()

    })
}

setImmediate(main)

// frida -Uf com.luoge.com -l test.js

